package com.zip;

import com.sun.org.apache.xpath.internal.compiler.Keywords;

import java.util.HashSet;
import java.util.Set;

/**
 * 敏感词数据脱敏
 * */
public class SensitiveWords {

    private static final String RE_STR = "*";

    /**
     * 内部类，用来嵌套所有的子节点
     * */
    public static class TreeNode{

        TreeNode[] childNode; //子节点

        boolean endKeyWord;//是否为最后节点

        //初始化
        TreeNode(){
            childNode = new TreeNode[Character.MAX_VALUE];//最大char 数组 用来对应中文，因为26个字母搞定
            endKeyWord = false;
        }
    }

    private TreeNode root;//父节点

    private Set<String> words;

    SensitiveWords(){
        root = new TreeNode();
        words = new HashSet<>();
    }

    /**
     * 添加关键词
     * @param word 关键词
     * */
    public void addWord(String word){
        //声明父节点
        TreeNode node = root;
        //遍历关键词
        for(char wordChar:word.toCharArray()){

            //如果为空，就创建子节点
            if(null == node.childNode[wordChar]){
                node.childNode[wordChar] = new TreeNode();
            }
            //赋值当前子节点为父节点，往下遍历，直到整个关键词都有对应的子节点
            node = node.childNode[wordChar];
        }
        node.endKeyWord = true;//是否为last节点，没有子节点了
        words.add(word);//添加进set数组
    }


    /**
     * 敏感词脱敏
     * @param word 敏感词
     * */
    public String dataMaskingNew(String word){

        //声明父节点
        TreeNode node = root;

        //偏移量
        int currentIndex = 0;

        //敏感词开始下标
        int startIndex = 0;

        //脱敏最终数据
        StringBuffer buf = new StringBuffer();


        //得到字符串的char数组
        char[] wordChar = word.toCharArray();

        while (currentIndex<word.length()){
            //取出当前char 对应的index
            char strChar = wordChar[currentIndex];
            //在脱敏父节点查找
            TreeNode childNode = node.childNode[strChar];

            if(null == childNode){

                //当前下标与start下标不一致时表示有first存在，但下级不存在
                if(currentIndex != startIndex){
                    //截取first字符进buf，first下一级从新遍历
                    buf.append(word, startIndex, startIndex+1);
                    String wordNew = word.substring(startIndex+1);
                    buf.append(this.dataMaskingNew(wordNew));
                    break;
                }

                buf.append(word, startIndex, currentIndex+1);
                currentIndex = currentIndex+1;
                startIndex = currentIndex;
                node = root;

            }else if(childNode.endKeyWord){
                buf.append(this.reStr(currentIndex-startIndex));
                currentIndex = currentIndex+1;
                startIndex = currentIndex;
                node = root;
            }else{
                currentIndex = currentIndex+1;
                node = childNode;
            }

        }

        return buf.toString();

    }



    private String reStr(int length){
        StringBuffer buf = new StringBuffer();
        for(int i=0;i<=length;i++){
            buf.append(RE_STR);
        }
        return buf.toString();
    }

    public static void main(String[] args) {
        SensitiveWords wordsOp = new SensitiveWords();
        wordsOp.addWord("这是什");
        wordsOp.addWord("哈");
        String str = "哈这哈这是什么23;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什;哈这是什哈1哈这是什";
        for(int i=0;i<5;i++){
            str = str+"魏闯李召金城"+str;
        }

        System.err.println(str.length());
        System.err.println("最终结果:"+
                wordsOp.dataMaskingNew(str)
        );//哈这

//        System.err.println("最终结果:"+wordsOp.dataMaskingNew("哈"));//哈这
//
//        System.err.println("最终结果:"+wordsOp.dataMaskingNew("这是什"));//哈这
//
//        System.err.println("最终结果:"+wordsOp.dataMaskingNew("哈这是什哈1哈这是什"));//哈这
//
//        System.err.println("最终结果:"+wordsOp.dataMaskingNew("这是什"));//哈这
//
//        System.err.println("最终结果:"+wordsOp.dataMaskingNew("这是什"));//哈这

        //System.err.println(wordsOp.DataMasking(""));
    }


}
